#include "taskAudioProcessed.h"
#include "FreeRTOS.h"
#include "task.h"
#include "appCommon.h"
#include "sai.h"
#include "stream_buffer.h"
#include "fifo.h"



#define BUFFER_NUM          2 //如果这里不是2的幂，需要修改 receiveIndex,sendIndex 溢出计算方式
#define DMA_RECEIVE_SIZE    FRAME_BUFFER_BYTES
#define DMA_SEND_SIZE       FRAME_BUFFER_BYTES

#define AUDIO_PROCESSED_SIZE    DMA_RECEIVE_SIZE

AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t dmaReceiveBuffer[DMA_RECEIVE_SIZE * BUFFER_NUM], 4);
AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t dmaSendBuffer[DMA_SEND_SIZE * BUFFER_NUM], 4);
#if (defined CFG_DATA_DEAL_FLOAT) && (CFG_DATA_DEAL_FLOAT > 0)
VARIABLE_ALIGN(static float audioReceiveBuffer[CFG_I2S_FRAME_SIZE * CFG_I2S_CHANNEL],32);
VARIABLE_ALIGN(static float audioSendBuffer[CFG_I2S_FRAME_SIZE * CFG_I2S_CHANNEL],32);
#else
VARIABLE_ALIGN(static AUDIO_VALUE_TYPE audioReceiveBuffer[CFG_I2S_FRAME_SIZE * CFG_I2S_CHANNEL],32);
VARIABLE_ALIGN(static AUDIO_VALUE_TYPE audioSendBuffer[CFG_I2S_FRAME_SIZE * CFG_I2S_CHANNEL],32);
#endif

int32_t receiveIndex;
int32_t sendIndex;
__S_FIFO fifo;
StreamBufferHandle_t streamReceive;
StreamBufferHandle_t streamSend;

extern TaskHandle_t hAudioProcessed;

#if (defined CFG_DATA_DEAL_FLOAT) && (CFG_DATA_DEAL_FLOAT > 0)
void audioDataProcess(float *input,float *output,uint32_t samples);
#else
void audioDataProcess(AUDIO_VALUE_TYPE *input,AUDIO_VALUE_TYPE *output,uint32_t samples);
#endif


void saiReceiveCallback(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdTRUE;

    vTaskNotifyGiveFromISR( hAudioProcessed, &xHigherPriorityTaskWoken );
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

void saiSendCallback(void)
{
}

void appTask_AudioProcessed(void *pvParameters)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    size_t xReceivedBytes;
    StaticStreamBuffer_t streamReceiveStruct;
    AUDIO_VALUE_TYPE *pSample;
    AUDIO_VALUE_TYPE intSample;
    receiveIndex = 0 ;
    sendIndex = 0 ;

    //清空发送buffer
    memset(audioSendBuffer,0,sizeof(audioSendBuffer));
    saiStartReceive(dmaReceiveBuffer,DMA_RECEIVE_SIZE);
    while(1)
    {
        //等待DMA接收完一帧
        ulTaskNotifyTake(pdTRUE,pdMS_TO_TICKS(portMAX_DELAY));
        //获取接收buffer数据地址
        pSample = (AUDIO_VALUE_TYPE *)(dmaReceiveBuffer + (FRAME_BUFFER_BYTES * receiveIndex));
        //切换buffer
        receiveIndex = (receiveIndex + 1) & (BUFFER_NUM - 1);
        //开始下一帧接收
        saiStartReceive(dmaReceiveBuffer + (FRAME_BUFFER_BYTES * receiveIndex),FRAME_BUFFER_BYTES);
        //把DMA buffer中的数据拷贝到 audioReceiveBuffer
        for(int i=0; i<(CFG_I2S_FRAME_SIZE * CFG_I2S_CHANNEL); i++)
        {
            intSample = *pSample++;
        #if CFG_I2S_WORDWIDTH == 24
            intSample >>= 8;
        #endif
        #if (defined CFG_DATA_DEAL_FLOAT) && (CFG_DATA_DEAL_FLOAT > 0)
            audioReceiveBuffer[i] = (float)((double)intSample / (double)(AUDIO_VALUE_MAX + 1));
        #else
            audioReceiveBuffer[i] = intSample ;
        #endif
        }
        //获取发送buffer数据地址
        pSample = (AUDIO_VALUE_TYPE *)(dmaSendBuffer + (DMA_SEND_SIZE * sendIndex));
        //一帧128个采样，立体声，直通延时大约4.12ms
    #if (defined CFG_BYPASS) && (CFG_BYPASS > 0)
        //数字直通，把接收到的数据与audioSendBuffer中的数据混合
        for(int i=0; i<(CFG_I2S_FRAME_SIZE * CFG_I2S_CHANNEL); i++)
        {
        #if (defined CFG_DATA_DEAL_FLOAT) && (CFG_DATA_DEAL_FLOAT > 0)
            audioSendBuffer[i] += audioReceiveBuffer[i];
            if(audioSendBuffer[i] > 1.0f)
            {
                audioSendBuffer[i] = 1.0f;
            }
            else if(audioSendBuffer[i] < -1.0f)
            {
                audioSendBuffer[i] = -1.0f;
            }
            *pSample = audioSendBuffer[i] * AUDIO_VALUE_MAX;
        #if CFG_I2S_WORDWIDTH == 24
            *pSample <<= 8;
        #endif
            pSample ++;
        #else
            audioSendBuffer[i] += audioReceiveBuffer[i];
            if(audioSendBuffer[i] > AUDIO_VALUE_MAX)
            {
                audioSendBuffer[i] = AUDIO_VALUE_MAX;
            }
            else if(audioSendBuffer[i] < AUDIO_VALUE_MIN)
            {
                audioSendBuffer[i] = AUDIO_VALUE_MIN;
            }
            *pSample = audioSendBuffer[i];
        #if CFG_I2S_WORDWIDTH == 24
            *pSample <<= 8;
            pSample++;
        #endif
        #endif
        }
    #endif
        //把要播放的数据通过DMA发送出去
        saiStartSend(dmaSendBuffer + (DMA_SEND_SIZE * sendIndex),DMA_SEND_SIZE);
        sendIndex = (sendIndex + 1) & (BUFFER_NUM - 1);
        //清空发送buffer
        memset(audioSendBuffer,0,sizeof(audioSendBuffer));
        //数据处理
        audioDataProcess(audioReceiveBuffer,audioSendBuffer,CFG_I2S_FRAME_SIZE);
    }
}

#if (defined CFG_DATA_DEAL_FLOAT) && (CFG_DATA_DEAL_FLOAT > 0)
void audioDataProcess(float *input,float *output,uint32_t samples)
#else
void audioDataProcess(AUDIO_VALUE_TYPE *input,AUDIO_VALUE_TYPE *output,uint32_t samples)
#endif
{
}

